package edu.buaa.traffic.transaction;

import com.google.common.collect.PeekingIterator;
import edu.buaa.common.transaction.AbstractTransaction;
import edu.buaa.utils.TemporalValue;
import edu.buaa.utils.TimePointInt;
import edu.buaa.utils.Helper;
import edu.buaa.utils.Pair;
import edu.buaa.utils.Triple;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class EntityHistoryTx extends AbstractTransaction {
    private int entity;
    private int beginTime;
    private int endTime;
    private String prop;

    public EntityHistoryTx(int entity, int beginTime, int endTime, String prop) {
        this.setTxType(TxType.tx_query_entity_history);
        this.entity = entity;
        this.beginTime = beginTime;
        this.endTime = endTime;
        this.prop = prop;
    }

    public EntityHistoryTx() {
        this.setTxType(TxType.tx_query_entity_history);
    }

    public int getEntity() {
        return entity;
    }

    public void setEntity(int entity) {
        this.entity = entity;
    }

    public int getBeginTime() {
        return beginTime;
    }

    public void setBeginTime(int beginTime) {
        this.beginTime = beginTime;
    }

    public int getEndTime() {
        return endTime;
    }

    public void setEndTime(int endTime) {
        this.endTime = endTime;
    }

    public String getProp() {
        return prop;
    }

    public void setProp(String prop) {
        this.prop = prop;
    }

    public static class Result extends AbstractTransaction.Result {
        List<Triple<Integer, Integer, Integer>> history;

        public List<Triple<Integer, Integer, Integer>> getHistory() {
            return history;
        }

        public void setHistory(List<Triple<Integer, Integer, Integer>> history) {
            this.history = history;
        }
    }

    @Override
    public boolean validateResult(AbstractTransaction.Result result) {
        return Helper.validateResult(conv(((Result) this.getResult()).getHistory()), conv(((Result) result).getHistory()));
    }

    public List<Pair<Integer, Integer>> conv(List<Triple<Integer, Integer, Integer>> from){
        TemporalValue<Integer> tv = new TemporalValue<>();
        for(Triple<Integer, Integer, Integer> f : from){
            tv.set(new TimePointInt(f.getLeft()), new TimePointInt(f.getMiddle()), Math.round(f.getRight()));
        }
        tv.mergeSameVal();
        PeekingIterator<Map.Entry<TimePointInt, Integer>> it = tv.pointEntries();
        List<Pair<Integer, Integer>> res = new ArrayList<>();
        while(it.hasNext()){
            Map.Entry<TimePointInt, Integer> p = it.next();
            res.add(Pair.of(p.getKey().val(), p.getValue()));
        }
        return res;
    }
}
